package miggy.dma;

import miggy.SystemModel;
import miggy.api.cpu.Size;
import miggy.api.memory.CustomRegisterObserver;
import miggy.memory.CustomRegisters;
import miggy.utils.TextUtil;

// $Revision: 21 $
public class CopperChannel extends BaseDMAChannel
{
	private boolean danger_bit;
	private int copList1;
	private int copList2;
	private int copList1Pos;
	private int copList2Pos;

	public CopperChannel()
	{
		super("Copper DMA Channel");
		initObservers();
		reset();
	}

	private void initObservers()
	{
		SystemModel.REGS.addObserver(CustomRegisters.COPCON, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				danger_bit = ((value & 0x0002) != 0);
				logger.info("COPCON: " + TextUtil.toHex((short)value));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COPJMP1, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				logger.info("COPJMP1: " + TextUtil.toHex((short)value));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COPJMP2, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				logger.info("COPJMP2: " + TextUtil.toHex((short)value));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COP1LCH, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				if(size == Size.Long)
				{
					//write full address
					copList1 = value;
				}
				else
				{
					//write word
					copList1 &= 0x0000ffff;
					copList1 |= (value << 16);
				}
				logger.info("COP1LCH: " + TextUtil.toHex(value, size));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COP1LCL, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				copList1 &= 0xffff0000;
				copList1 |= (value & 0x0000ffff);
				logger.info("COP1LCL: " + TextUtil.toHex((short)value));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COP2LCH, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				if(size == Size.Long)
				{
					//write full address
					copList2 = value;
				}
				else
				{
					//write word
					copList2 &= 0x0000ffff;
					copList2 |= (value << 16);
				}
				logger.info("COP2LCH: " + TextUtil.toHex(value, size));
			}
		});

		SystemModel.REGS.addObserver(CustomRegisters.COP2LCL, new CustomRegisterObserver() {
			public void update(int register, int value, Size size)
			{
				copList2 &= 0xffff0000;
				copList2 |= (value & 0x0000ffff);
				logger.info("COP2LCL: " + TextUtil.toHex((short)value));
			}
		});
	}

	public void reset()
	{
		enabled = false;
		danger_bit = false;
		copList1 = 0;
		copList2 = 0;
		copList1Pos = 0;
		copList2Pos = 0;
	}

	public int doWork(int scanline)
	{
		//not sure we can do this as we need to copy the bitplane data to the display here too
		if(!enabled)
			return 0;

		return 0;
	}
}
